
/* Generated by Interface Builder */

#import "WorkspaceManager.h"
#import "MenuManager.h"
#import <appkit/Text.h>
#import <appkit/Panel.h>
#import <objc/objc-load.h>
#import <stdlib.h>
#import <strings.h>
#import  <sys/file.h>
#import <sys/types.h>
#import <sys/stat.h>
#import <libc.h>

@implementation WorkspaceManager

- evalSelection:sender
{ // compile and run the workspace selection
  char *textBuf, *headerBuf, *cursor, *trueBuf, comBuf[128] ;
  char tmpFile[20] = "CBXXXXXX" ;
  char *moduleNames[2] ;
  NXStream *aStream ;
  NXSelPt start, end ;
  FILE *fp ;
  int textLen, maxLen ;

  [self message: "Creating temporary class..."] ;
  // get the selected text
  [textView getSel:&start :&end] ;
  textLen = end.cp-start.cp ;
  textBuf = trueBuf = (char *) malloc(textLen) ; 
  [textView getSubstring:textBuf start:start.cp length:textLen] ;
  textBuf[textLen] = '\0' ;
  // now find out if we have any header
  headerBuf = textBuf ;
  while(*headerBuf == ' ' || *headerBuf == '\n' || *headerBuf == '\t')
    headerBuf++ ;  // scan past any initial whiteSpace
  if(!strncmp(headerBuf,"#header",7)) // then we have a header
  { headerBuf += 7 ; // header starts after #header
    cursor = headerBuf ;
    while(strncmp(cursor,"#endheader", 10)) // find end of header 
    {  cursor++ ;
       cursor = index(cursor,'#') ; // try next hash sign
       if(cursor == (char *) 0) // then no #endheader
       { NXRunAlertPanel("CB","Error: no #endheader line found",
             NULL,NULL,NULL) ;
	 free(textBuf) ;
         return self ;
       }
    }
    textBuf = &cursor[10] ;
    *cursor = '\0' ; // chop string into 2 pieces    
  }
  else
    cursor = headerBuf = "" ;   // no header at all

  // now hack up the file...
  mktemp(tmpFile) ;
  sprintf(comBuf,"/tmp/%s.m",tmpFile) ;
  fp = fopen(comBuf,"w+") ;
  fprintf(fp,
   "%s\n"
   "#import <objc/Object.h>\n"
   "#import <objc/HashTable.h>\n"
   "@interface DictManager: Object ;\n"
   "+ initialize ;\n"
   "+ inserKey: (char *) aKey value: (void *) data type: (char *) aType ;\n"
   "+ (void *) valueForKey: (char *) aKey type: (char *) aType ;\n"
   "@end\n"
   "extern id NXApp;\n"
   "@interface Doit: Object\n"
   "+(void) doit ;\n"
   "@end\n\n"
   "@implementation Doit\n"
   "+ (void) doit\n"
   "{\n"
   "#line 1\n"
   "%s\n"
   "}\n"
   "@end",
   headerBuf, textBuf) ;
  fflush(fp) ;
  fclose(fp) ;
  
  // free up alloc'ed memory
  if(headerBuf[0] != '\0') // string was cut into 2 pieces...
    *cursor = ' ' ;   // reassemble
  free(trueBuf) ; // trueBuf always points to beginning of malloc'ed string

  // compile and load the file
  [self message: "Compiling..."] ;
  sprintf(comBuf, "cc -c -I /usr/include/objc -Wall -o /tmp/%s.o /tmp/%s.m"
          " 2> /tmp/%s", tmpFile, tmpFile, tmpFile) ;
  if(system(comBuf)) // non-zero exit status == must report the errors
  { sprintf(comBuf,"/tmp/%s",tmpFile) ;
    [NXApp appendFileToTranscript: comBuf] ;
    NXRunAlertPanel("CB","Compilation errors: see Transcript Window\n",
         NULL,NULL,NULL) ;
    sprintf(comBuf,"rm /tmp/%s.m /tmp/%s.o /tmp/%s 2> /dev/null",
         tmpFile,tmpFile,tmpFile) ;
    system(comBuf) ;
    [self message: ""] ;
    return self ;
  } 
  [self message: "Loading..."] ;
  aStream = NXOpenMemory(NULL, 0, NX_READWRITE) ;
  sprintf(comBuf,"/tmp/%s.o",tmpFile) ;
  moduleNames[0] = comBuf ;
  moduleNames[1] = NULL ;
  objc_loadModules(moduleNames, aStream, NULL, NULL, NULL) ;
  NXPutc(aStream,'\0') ; 
  NXGetMemoryBuffer(aStream, &textBuf, &textLen, &maxLen);
  [NXApp printf: textBuf];
  [self message: "Executing..."] ;
  objc_msgSend(objc_getClass("Doit"),
     sel_getUid("doit")) ;
  [self message: ""] ;
  objc_unloadModules(aStream, NULL) ;
  NXCloseMemory(aStream,NX_TRUNCATEBUFFER) ;
  sprintf(comBuf,"rm /tmp/%s.m /tmp/%s.o /tmp/%s 2> /dev/null",
         tmpFile,tmpFile,tmpFile) ;
  system(comBuf) ;
  return self ;
}

- (char *) extension ;
{ // provide file extension
  return "wsp" ;
}

@end
